"""
任务执行器基类和抽象接口
实现策略模式，支持不同的执行策略
"""

from loguru import logger
import traceback
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Any, Optional

from app.models.task.task_data import Task, TaskStatus, TaskType
from app.core.task_scheduler.task_registry import task_registry
from app.core.sse_manager import sse_manager


class BaseTaskExecutor(ABC):
    """任务执行器抽象基类"""

    def __init__(self, name: str):
        self.name = name
        self.is_running = False

    @abstractmethod
    async def execute_task(self, task: Task) -> Any:
        """执行任务 - 子类必须实现"""
        pass

    async def run_task(self, task: Task) -> Task:
        """运行任务的完整流程"""
        logger.info(f"开始执行任务: {task.name} (ID: {task.id})")

        # 更新任务状态为运行中
        task.status = TaskStatus.RUNNING
        task.started_at = datetime.now()
        await sse_manager.send_task_update(task)

        try:
            # 执行任务
            result = await self.execute_task(task)

            # 更新任务状态为完成
            task.result = result
            task.status = TaskStatus.COMPLETED
            task.completed_at = datetime.now()

            logger.info(f"任务执行完成: {task.name}")

        except Exception as e:
            # 处理执行异常
            error_msg = f"{str(e)}\n{traceback.format_exc()}"
            task.error = error_msg
            task.status = TaskStatus.FAILED
            task.completed_at = datetime.now()

            logger.error(f"任务执行失败: {task.name}, 错误: {str(e)}")

            # 检查是否需要重试
            if task.retry_count < task.max_retries:
                task.retry_count += 1
                task.status = TaskStatus.RETRYING
                logger.info(f"任务将重试: {task.name}, 重试次数: {task.retry_count}")

        # 发送任务更新通知
        await sse_manager.send_task_update(task)
        return task

    def get_function(self, func_name: str):
        """获取注册的函数"""
        return task_registry.get_function(func_name)

    def start(self):
        """启动执行器"""
        self.is_running = True
        logger.info(f"执行器已启动: {self.name}")

    def stop(self):
        """停止执行器"""
        self.is_running = False
        logger.info(f"执行器已停止: {self.name}")


class BaseTaskStorage(ABC):
    """任务存储抽象基类"""

    @abstractmethod
    async def save_task(self, task: Task) -> None:
        """保存任务"""
        pass

    @abstractmethod
    async def get_task(self, task_id: str) -> Optional[Task]:
        """获取任务"""
        pass

    @abstractmethod
    async def update_task(self, task: Task) -> None:
        """更新任务"""
        pass

    @abstractmethod
    async def delete_task(self, task_id: str) -> bool:
        """删除任务"""
        pass

    @abstractmethod
    async def list_tasks(
        self,
        status: Optional[TaskStatus] = None,
        task_type: Optional[TaskType] = None,
        limit: Optional[int] = None,
    ) -> list[Task]:
        """列出任务"""
        pass

    @abstractmethod
    async def get_tasks_count(self) -> dict[TaskStatus, int]:
        """获取任务统计"""
        pass
